/* jjmenu - context menu jquery plugin
 * http://jursza.net/dev/jjmenu/
 *  
 * @author Jacek Jursza (okhan.pl@gmail.com)
 * @version 1.1.1
 * @date 2010-01-04
 * @category jQuery plugin
 * @copyright (c) 2009 Jacek Jursza (http://jursza.net/)
 * @licence MIT [http://www.opensource.org/licenses/mit-license.php]    
 */

(function($){  
   
    $.fn.jjmenu = function (clickEvent, param, myReplaces, effect) {

        var global = this;
        var acceptEvent = false;
		

        if ( clickEvent == "rightClick" || clickEvent == "both" )
        {
            global.mousedown(function(event) {
                if (event.button == 2 && (clickEvent == "rightClick" || clickEvent == "both")) { // right click
                    global.pageX = event.pageX;
                    global.pageY = event.pageY;
                    event.preventDefault();
                    event.stopPropagation();
                    var mmain = new menu("main", param, myReplaces, this, effect);
                    $(this)[0].oncontextmenu = function() {
                        return false;
                    }
                    $(this).unbind('mouseup');
                    $(this).blur();
                    return false;
                }
            });
			
            document.body.oncontextmenu = function() {
                if ($("div[id^=jjmenu_main]").length) return false;
            }			
        }
		
        if ( clickEvent == "click" || clickEvent == "both" )
        {
            global.click(
                function(event) {
                    if (this == event.target) {
                        global.pageX = event.pageX;
                        global.pageY = event.pageY;
                        event.preventDefault();
                        event.stopPropagation();
                        var mmain = new menu("main", param, myReplaces, this, effect);
                        $(this).blur();
                        return false;
                    }
                });
        }

        $(document).click(function(event) {
            if (event.button!=2) $("div[id^=jjmenu]").remove();
        });
        $("#MySplitter").click(function(event) {
            if (event.button!=2) $("div[id^=jjmenu]").remove();
        });

        /* Menu obeject */
        function menu(id,param,myReplaces,el,effect) {
		
            var effect = getEffect(id, effect);
			
            if (id == "main") window.triggerElement = el;
            $("div[id^=jjmenu_"+id+"]").remove();
			
            var m  = document.createElement('div');
            var ms = document.createElement('span');
            $(m).append(ms);
			
            m.className = "jjmenu";
            m.id = "jjmenu_"+id;
            $(m).css({
                display:'none'
            });
            $(document.body).append(m);
			
            positionMenu();

            var dynamicItems = false;
			
            for (var i in param) {
				
                if (param[i].get) {
					
                    dynamicItems = true;
                    $.getJSON(uReplace(param[i].get), function(data) {
                        for (var ii in data) {
                            putItem(data[ii]);
                        }
                        checkPosition();
                    })
                    $(this).ajaxError( function() {
                        checkPosition();
                    });
                }
                else if (param[i].getByFunction) {
					
                    if  (typeof(param[i].getByFunction) == "function") {
                        var uF = param[i].getByFunction;
                    }
                    else {
                        var uF = eval(param[i].getByFunction);
                    }
                    var uItems = uF(myReplaces);
                    for (var ii in uItems) {
                        putItem(uItems[ii]);
                    }
                    checkPosition();
                }
                else {
                    putItem(param[i]);
                }
            }
			
            if (!dynamicItems) checkPosition();
            showMenu();
			
            /* first position menu */
            function positionMenu() {
                var tempX=0;
                var tempY=0;
               
                tempX = global.pageX
                tempY = global.pageY              
                // catch possible negative values in NS4
                if (tempX < 0){
                    tempX = 0
                }
                if (tempY < 0){
                    tempY = 0
                }
                tempX+=5;
                $(m).css({
                    position:"absolute",
                    top:tempY+"px",
                    left:tempX+"px"
                });
            }
			
            /* correct menu position */
            function checkPosition() {

                var isHidden = $(m).css("display") == "none" ? true : false;
                var noAuto = false;
				
                if (effect.orientation == "top" || effect.orientation == "bottom") {
                    noAuto = true;
                }
			
                if (isHidden) $(m).show();
                var positionTop = $(m).offset().top;
                var positionLeft = $(m).offset().left;
                if (isHidden) $(m).hide();
			
                var xPos = positionTop - $(window).scrollTop();
	            
                $(m).css({
                    left:"0px"
                });
                var menuHeight = $(m).outerHeight();
                var menuWidth = $(m).outerWidth();
                $(m).css({
                    left:positionLeft+"px"
                });
                
                var nleft = positionLeft;
                if ( positionLeft + menuWidth > $(window).width() ) {
                    nleft = $(window).width() - menuWidth;
                }
                				
                var spaceBottom = true;
                if (effect.yposition == "auto" && effect.xposition == "left") {
					
                    if ( xPos + menuHeight + $(el).outerHeight() > $(window).height()) {
                        spaceBottom = false;
                    }
                }
                else {
    				
                    if ( xPos + menuHeight  > $(window).height()) {
                        spaceBottom = false;
                    }
                }				

                var spaceTop = true;
                if (positionTop - menuHeight <  0) {
                    spaceTop = false;
                }
				
                if (effect.yposition == "bottom") {
                    positionTop = positionTop + $(el).outerHeight();
                }
				
                if ( (effect.orientation == "auto" && spaceBottom == false && spaceTop == true) || effect.orientation == "top") {
                    // top orientation
                    var ntop = parseInt(positionTop,10) - parseInt(menuHeight,10);
                    $(m).addClass("topOriented");

                } else {
                    // bottom orientation
                    $(m).addClass("bottomOriented");
                    if (effect.yposition == "auto" && effect.xposition == "left") {
                        positionTop = positionTop + $(el).outerHeight();
                    }
                    var ntop = parseInt(positionTop,10);
                }
				
                $(m).css({
                    "top":ntop+"px",
                    "left":nleft+"px"
                });
            }
			
            /* show menu depends to effect.show */
            function showMenu() {

                if (!effect || effect.show == "default") {
                    $(m).show();
                    return false;
                }
				 
                var speed = parseInt(effect.speed);
                speed = isNaN(speed) ? 500 : speed;
				   
                switch (effect.show)
                {
                    case "fadeIn":
                        $(m).fadeIn(speed);
                        break;
					  
                    case "slideDown":
                        $(m).slideDown(speed);
                        break;
					  
                    default:
                        $(m).show();
                        break;
                }
            }
			
            /* put item to menu */
            function putItem(n) {
				
                var item = document.createElement('div');
                $(item).hover(function(){
                    $(this).addClass("jj_menu_item_hover")
                },
                function(){
                    $(this).removeClass("jj_menu_item_hover")
                });
				
                $(item).click( function(event) {
                    event.stopPropagation();
                    doAction(n.action);
                });
				
                var span = document.createElement('span');
                $(item).append(span);
				  

                switch (n.type)
                {
                    case "sub":
                        item.className = "jj_menu_item jj_menu_item_more";
                        $(item).click(function() {
                            if ($("#jjmenu_"+id+"_sub").length > 0) {
                                $("div[id^=jjmenu_"+id+"_sub]").remove();
                            }
                            else {
                                var sub = new menu(id+"_sub", n.src, myReplaces, this, effect);
                            }
                        });
                        break;
					
                    default:
                        $(item).hover(function() {
                            $("div[id^=jjmenu_"+id+"_sub]").remove();
                        });
                        item.className = "jj_menu_item";
                        break;
                }
				
				
                if (n.customClass && n.customClass.length>0) {
                    jQuery(span).addClass(n.customClass);
                }
				
                $(span).html(uReplace(n.title));
                $(ms).append(item);
            }
			
            /* do action on menu item */
            function doAction(act) {
			
                if (act) {
					
                    switch (act.type) {
						
                        case "gourl":
                            if (act.target) {
                                var newWindow = window.open(uReplace(act.url), act.target);
                                newWindow.focus();
                                return false;
                            }
                            else {
                                document.location.href=uReplace(act.url);
                            }
                            break;
						
                        case "ajax":
                            $.getJSON(uReplace(act.url), function(data) {
							
                                var cb = eval(act.callback);
                                if (typeof(cb) == "function") {
                                    cb(data);
                                }
							
                            });
                            break;
						
                        case "fn":
                            var cb = eval(act.callback);
                            if (typeof(cb) == "function") {
                                cb(myReplaces);
                            }
                            break;
                    }
                }
            }
			
            /* replace string with user parameters */
            function uReplace(str) {
                if (myReplaces) {
                    for (var u in myReplaces) {
                        str = str.replace("#"+u+"#", eval("myReplaces."+u));
                    }
                }
                return str;
            }

            /* get effect opbject */
            function getEffect(id, effect) {
			
                var defEffect = {
                    show:"default",
                    xposition:"right",
                    yposition:"auto",
                    orientation:"auto"
                };

                if (!effect) {
                    return defEffect;
                }

                if (!effect.show) effect.show = "default";
						  
                var show = effect.show;

                if (!effect.xposition) effect.xposition = "right";
                if (!effect.yposition) effect.yposition = "auto";
                if (!effect.orientation) effect.orientation = "auto";

                if (id != "main") {
                    var subeffect = defEffect;
                    subeffect.show = show;
                }

                return ( id == "main" ) ? effect : subeffect;
            }
        } // !menu
    };
   
})(jQuery); 